package sfile

import (
	"fmt"
	"github.com/Caisin/sfile/utils"
	"github.com/panjf2000/ants/v2"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

// CheckSFile 校验S文件金额,数量
func CheckSFile(dir string, poolSize int) {
	totalFiles := utils.GetFiles(dir, func(path string, name string) bool {
		return strings.Index(name, "total.log") > 0
	})
	if len(totalFiles) == 0 {
		log.Println("total files is empty!")
	}
	fileTotalMap := make(map[string]map[string]int64)
	for _, totalFile := range totalFiles {
		totalFileDir := filepath.Dir(totalFile)
		lines := utils.ReadLines(totalFile)
		for i := range lines {
			if len(lines[i]) == 0 {
				continue
			}
			line := lines[i]
			lineDatas := strings.Split(line, ",")
			if len(lineDatas) != 4 {
				log.Printf("line data[%s] formate error!", line)
			}

			sfileName := strings.Split(lineDatas[0], "=")[1]
			sfilePath := filepath.Join(totalFileDir, sfileName)
			recordNum, err := strconv.ParseInt(strings.Split(lineDatas[1], "=")[1], 10, 64)
			if err != nil {
				log.Printf("total File [%v] line [%v] recordNum parse recordNum error", totalFile, line)
			}
			totalFee, err := strconv.ParseInt(strings.Split(lineDatas[2], "=")[1], 10, 64)
			totalBalance, err := strconv.ParseInt(strings.Split(lineDatas[3], "=")[1], 10, 64)
			totalData := fileTotalMap[sfilePath]
			if totalData == nil {
				totalData = make(map[string]int64)
			}
			totalData["recordNum"] += recordNum
			totalData["totalFee"] += totalFee
			totalData["totalBalance"] += totalBalance
			fileTotalMap[sfilePath] = totalData
		}
	}
	chckResult := true
	if pool, err := ants.NewPool(poolSize); err == nil {
		defer pool.Release()
		var wg sync.WaitGroup
		for key := range fileTotalMap {
			wg.Add(1)
			data := fileTotalMap[key]
			sfilePath := key
			_ = pool.Submit(func() {
				recordNum := data["recordNum"]
				totalFee := data["totalFee"]
				totalBalance := data["totalBalance"]
				sfileLines := utils.ReadLines(sfilePath)
				recNum := len(sfileLines) - 1
				if int64(recNum) != recordNum {
					chckResult = false
					log.Printf("S File [%v] recordNum is [%v] total file recordNum is [%v]", sfilePath, recNum, recordNum)
				}
				sfileTotalFee := int64(0)
				sfileTotalBalance := int64(0)
				for _, sfileLine := range sfileLines {
					if len(sfileLine) == 0 {
						continue
					}
					items := strings.Split(sfileLine, ",")
					fee, _ := strconv.ParseInt(items[5], 10, 64)
					balance, _ := strconv.ParseInt(items[6], 10, 64)
					sfileTotalFee += fee
					sfileTotalBalance += balance
				}
				if totalFee != sfileTotalFee {
					chckResult = false
					log.Printf("S File [%v] totalFee is [%v] total file totalFee is [%v]", sfilePath, sfileTotalFee, totalFee)
				}
				if totalBalance != sfileTotalBalance {
					chckResult = false
					log.Printf("S File [%v] totalFee is [%v] total file totalFee is [%v]", sfilePath, sfileTotalBalance, totalBalance)
				}
				wg.Done()
			})
		}
		wg.Wait()
	}
	if !chckResult {
		panic(fmt.Sprintf("dir[%v] S File check error", dir))
	}
	log.Printf(fmt.Sprintf("dir [%v] S File check successful!", dir))
}

// CheckOweFeeMinAcctDay 校验欠费表入库文件最小欠费账期
func CheckOweFeeMinAcctDay(dir string) {
	files := utils.GetFiles(dir, func(path string, name string) bool {
		return strings.Index(name, "ACCTOWEFEE") >= 0
	})
	pool, _ := ants.NewPool(100)
	defer pool.Release()
	var errorLines []string
	var wg sync.WaitGroup
	for i := range files {
		wg.Add(1)
		file := files[i]
		_ = pool.Submit(func() {
			if readFile, err := ioutil.ReadFile(file); err == nil {
				content := string(readFile)
				lines := strings.Split(content, "\n")
				for _, line := range lines {
					split := strings.Split(line, ",")
					if len(split) > 2 {
						s := split[2]
						parseInt, err := strconv.ParseInt(s, 10, 64)
						if err != nil || parseInt == -1 {
							errorLines = append(errorLines, line)
						}
					}
				}
			}
			wg.Done()
		})
	}
	wg.Wait()
	_ = os.Remove(dir + "/errorinfo")
	join := strings.Join(errorLines, "\n")
	_ = ioutil.WriteFile(dir+"/errorinfo", []byte(join), 777)
	fmt.Printf("错误信息%s", join)
}
